/*
 * author      : dormi330
 * date        : 2018/6/27
 * description : 申请退款操作
 */

package com.deep.trade.domain.refund;

import com.deep.trade.common.CommonUtils;
import com.deep.trade.common.DateUtils;
import com.deep.trade.common.TradeException;
import com.deep.trade.domain.order.TradeOrder;
import com.deep.trade.domain.order.TradeOrderSku;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CommandApplyRefund {

    @Autowired
    private RefundRepository refundRepository;

    public void applyRefund(
            TradeOrder tradeOrder
            , String skuIds // 逗号分隔的 sku id, 如果为null, 表示整个tradeOrder中的都在退款申请之列
            , BigDecimal refundMoney
            , RefundType refundType
            , String description
    ) throws TradeException {
        if (null == tradeOrder) throw new TradeException("tradeOrder not exists");
        if (null == refundType) throw new TradeException("refund type not exists");

        List<TradeOrderSku> refundApplySkuList;
        RefundOrder refundOrder = new RefundOrder();
        refundOrder.setId(CommonUtils.uuid());

        // 1. 处理退款的 sku id
        if (CommonUtils.stringNotBlankAndNull(skuIds)) {
            List<String> skuIdList = Arrays.asList(skuIds.split(","));
            refundApplySkuList = tradeOrder
                    .getSkuList()
                    .stream()
                    .filter(tradeOrderSku -> skuIdList.indexOf(tradeOrderSku.getSkuId()) != -1)
                    .collect(Collectors.toList());
        } else {
            refundApplySkuList = tradeOrder.getSkuList();
        }
        refundOrder.setSkuList(refundApplySkuList);

        // 2. 钱不能超过支付金额, 不能少于0
        // 如果不填, 表示按付款金额退款
        if (refundMoney == null) {
            refundMoney = BigDecimal.ZERO;
            for (TradeOrderSku tradeOrderSku : refundApplySkuList) {
                refundMoney = refundMoney.add(tradeOrderSku.getPayMoney());
            }
        }
        if (BigDecimal.ZERO.compareTo(refundMoney) == 1
                || refundMoney.compareTo(tradeOrder.getPayMoney()) == 1)
            throw new TradeException("refund amount illegal");
        refundOrder.setRefundMoney(refundMoney);

        // 3. 处理其他平庸字段
        refundOrder.setCreatedAt(new Date());
        refundOrder.setMemberId(tradeOrder.getMemberId());
        refundOrder.setSellerId(tradeOrder.getSellerId());
        refundOrder.setShopId(tradeOrder.getShopId());

        refundOrder.setTradeOrderId(tradeOrder.getId());
        refundOrder.setRefundTypeId(refundType.getId());
        refundOrder.setRefundTypeCode(refundType.getTypeCode());
        refundOrder.setRefundTypeName(refundType.getTypeName());
        refundOrder.setDescription(description);
        refundOrder.setStatus(RefundOrderStatusEnum.MEMBER_APPLIED.name);
        refundOrder.setActionDeadline(DateUtils.daysAfterNow(RefundOrder.MAX_WAITING_DAYS));

        // 保存
        refundRepository.insertRefundApply(refundOrder);
    }
}
